﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.ServiceModel;
using BackupObjects;

namespace BackupWebServicesRole
{    
    /// <summary>
    /// Backup client API
    /// </summary>
    [ServiceContract]
    public interface IBackupWebService
    {
        /// <summary>
        /// Load a file based on the id of the file.
        /// </summary>
        /// <param name="id">The id of the file.</param>
        /// <param name="userName">The name of the user that owns the file.</param>
        /// <param name="credentials">The user credentials.</param>
        /// <returns>The file entity.</returns>
        [OperationContract]
        BackupEntity LoadById(Guid id, string userName, Credentials credentials);

        /// <summary>
        /// Load a file based on the name of the file.
        /// </summary>
        /// <param name="name">The name of the file.</param>
        /// <param name="userName">The name of the user that owns the file.</param>
        /// <param name="credentials">The user credentials.</param>
        /// <returns>The file entity.</returns>
        [OperationContract]
        BackupEntity LoadByName(string name, string userName, Credentials credentials);

        /// <summary>
        /// Load all the files of a given user.
        /// </summary>
        /// <param name="userName">The name of the user.</param>
        /// <param name="credentials">The user credentials.</param>
        [OperationContract]
        void LoadAll(string userName, Credentials credentials);

        /// <summary>
        /// Savea given file.
        /// </summary>
        /// <param name="backupEntity">The file that need to be saved.</param>
        /// <param name="credentials">The user credentials.</param>
        [OperationContract]
        void Save(BackupEntity backupEntity, Credentials credentials);

        /// <summary>
        /// Delete a specific file.
        /// </summary>
        /// <param name="id">The id of the file.</param>
        /// <param name="userName">The owner of the file.</param>
        /// <param name="credentials">The user credentials.</param>
        [OperationContract]
        void Delete(Guid id, string userName, Credentials credentials);

        /// <summary>
        /// Get a stream of a specific file.
        /// </summary>
        /// <param name="id">The id of the file.</param>
        /// <param name="userName">The owner of the file.</param>
        /// <param name="credentials">The user credentials.</param>
        /// <returns>The stream of the file.</returns>
        [OperationContract]
        Stream GetBackupStream(Guid id, string userName, Credentials credentials);
    }

    [DataContract]
    public class Credentials
    {
        [DataMember]
        public string User { get; set; }

        [DataMember]
        public string Password { get; set; }
    }

    [DataContract]
    public class BackupEntity
    {
        public BackupEntity()
        {
            Id = Guid.NewGuid();
            Visibility = VisibilityBackup.Private;
        }

        internal BackupEntity(BackupObject backupObject)
            : this()
        {
            Id = backupObject.ID;
            Name = backupObject.Name;
            Visibility = backupObject.Visibility;
            OriginalFileName = backupObject.OriginalFileName;
            Description = backupObject.Description;
            UploadDate = backupObject.UploadDate;
            UploadBy = backupObject.UploadBy;
            if (backupObject.Contents != null)
            {
                Contents = (byte[]) backupObject.Contents.Clone();
            }
        }

        [DataMember]
        public Guid Id { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public string Description { get; set; }

        [DataMember]
        public byte[] Contents { get; set; }

        [DataMember]
        public string UploadBy { get; set; }

        [DataMember]
        public DateTime UploadDate { get; set; }

        [DataMember]
        public VisibilityBackup Visibility { get; set; }

        [DataMember]
        public string OriginalFileName { get; set; }

        public static implicit operator BackupEntity(BackupObject backupObject)
        {
            return new BackupEntity(backupObject);
        }

        public static implicit operator BackupObject(BackupEntity backupEntity)
        {
            return new BackupObject()
            {
                ID = backupEntity.Id,
                Name = backupEntity.Name,
                Description = backupEntity.Description,
                Contents = (byte[])backupEntity.Contents.Clone(),
                OriginalFileName = backupEntity.OriginalFileName,
                UploadBy = backupEntity.UploadBy,
                UploadDate = backupEntity.UploadDate,
                Visibility = backupEntity.Visibility
            };
        }
    }
}
